home *** CD-ROM | disk | FTP | other *** search
- #include "global.h"
- #include "mbuf.h"
- #include "timer.h"
- #include "iface.h"
- #include "cmdparse.h"
- #include "rspf.h"
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: rspfcmd.c,v 1.15 1997/09/07 21:18:28 root Exp root $";
- #endif
-
- #ifdef RSPF
-
-
- int Rspfownmode = -1;
- static int dointerface (int argc, char *argv[], void *p);
- static int domessage (int argc, char *argv[], void *p);
- static int domaxping (int argc, char *argv[], void *p);
- static int dorspfmode (int argc, char *argv[], void *p);
- static int dorrhtimer (int argc, char *argv[], void *p);
- static int dotimer (int argc, char *argv[], void *p);
- static int doroutes (int argc, char *argv[], void *p);
- static int dorspfstatus (int argc, char *argv[], void *p);
- static int dosuspect (int argc, char *argv[], void *p);
- int dorspf (int argc, char **argv, void *p);
- static struct timer rrhtimer, rspftimer;
-
- static const char norspf[] = "RSPF is not active - define interface first.\n";
-
- #ifdef AUTOROUTE
- int RspfActive = 0;
- extern int Ax25_autoroute;
- #endif
-
-
- static struct cmds Rspfcmds[] =
- {
- { "interface", dointerface, 0, 0, NULLCHAR},
- { "message", domessage, 0, 0, NULLCHAR},
- { "maxping", domaxping, 0, 0, NULLCHAR},
- { "mode", dorspfmode, 0, 0, NULLCHAR},
- { "rrhtimer", dorrhtimer, 0, 0, NULLCHAR},
- { "routes", doroutes, 0, 0, NULLCHAR},
- { "status", dorspfstatus, 0, 0, NULLCHAR},
- { "suspecttimer", dosuspect, 0, 0, NULLCHAR},
- { "timer", dotimer, 0, 0, NULLCHAR},
- { NULLCHAR, NULL, 0, 0, NULLCHAR}
- };
-
-
- int
- dorspf (int argc, char **argv, void *p)
- {
- return subcmd (Rspfcmds, argc, argv, p);
- }
-
-
- /* The suspect timer controls how often old links expire. When a link has
- * expired, we try to renew its entry by various methods.
- */
- static int
- dosuspect (int argc, char *argv[], void *p OPTIONAL)
- {
- if (Rspfifaces == NULLRIFACE) {
- tputs (norspf);
- return 0;
- }
- if (argc < 2) {
- tprintf ("Suspect timer: %lu/%lu seconds\n",
- read_timer (&Susptimer) / 1000,
- dur_timer (&Susptimer) / 1000);
- return 0;
- }
- Susptimer.func = rspfsuspect; /* what to call on timeout */
- Susptimer.arg = NULL; /* dummy value */
- set_timer (&Susptimer, atol (argv[1]) * 1000L); /* set timer duration */
- start_detached_timer (&Susptimer); /* and fire it up */
- return 0;
- }
-
-
- /* The RRH timer controls the interval between Router-To-Router Hello
- * messages. These messages announce that your station is live and well
- * and that you are willing to exchange RSPF routing updates.
- */
- static int
- dorrhtimer (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- if (Rspfifaces == NULLRIFACE) {
- tputs (norspf);
- return 0;
- }
- if (argc < 2) {
- tprintf ("RRH timer: %lu/%lu seconds\n",
- read_timer (&rrhtimer) / 1000,
- dur_timer (&rrhtimer) / 1000);
- return 0;
- }
- rrhtimer.func = rspfevent; /* what to call on timeout */
- rrhtimer.arg = (void *) &rrhtimer;
- set_timer (&rrhtimer, atol (argv[1]) * 1000L); /* set timer duration */
- start_detached_timer (&rrhtimer);/* and fire it up */
- return 0;
- }
-
-
- /* This timer controls the interval between the RSPF routing updates. */
- static int
- dotimer (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- if (Rspfifaces == NULLRIFACE) {
- tputs (norspf);
- return 0;
- }
- if (argc < 2) {
- tprintf ("RSPF update timer: %lu/%lu seconds\n",
- read_timer (&rspftimer) / 1000,
- dur_timer (&rspftimer) / 1000);
- return 0;
- }
- rspftimer.func = rspfevent; /* what to call on timeout */
- rspftimer.arg = (void *) &rspftimer;
- set_timer (&rspftimer, atol (argv[1]) * 1000L); /* set timer duration */
- start_detached_timer (&rspftimer); /* and fire it up */
- return 0;
- }
-
-
- /* Called when either the RRH timer, the Update timer or the Suspect timer
- * expires.
- */
- void
- rspfevent (t)
- void *t;
- {
- int cmd;
- struct mbuf *bp;
- struct rspfadj *adj = NULLADJ;
- struct timer *tp;
-
- tp = (struct timer *) t;
- if (tp == &rrhtimer) {
- cmd = RSPFE_RRH;
- start_detached_timer (tp);
- } else if (tp == &rspftimer) {
- cmd = RSPFE_UPDATE;
- start_detached_timer (tp);
- } else {
- for (adj = Adjs; adj != NULLADJ; adj = adj->next)
- if (&adj->timer == tp)
- break;
- if (adj == NULLADJ)
- return;
- cmd = RSPFE_CHECK;
- }
- bp = ambufw (1 + sizeof (int32));
- *bp->data = uchar (cmd);
- memcpy (bp->data + 1, &adj, sizeof (adj));
- bp->cnt = bp->size;
- enqueue (&Rspfinq, bp);
- }
-
-
- static int
- domessage (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- if (argc > 2) {
- tputs ("Usage: rspf message \"<your message>\"\n");
- return 0;
- }
- if (argc < 2) {
- if (Rrh_message != NULLCHAR)
- tputs (Rrh_message);
- } else {
- if (Rrh_message != NULLCHAR) {
- free (Rrh_message);
- Rrh_message = NULLCHAR; /* reset the pointer */
- }
- if (!strlen (argv[1]))
- return 0; /* clearing the buffer */
- Rrh_message = mallocw (strlen (argv[1]) + 5); /* allow for EOL */
- strcpy (Rrh_message, argv[1]);
- strcat (Rrh_message, INET_EOL); /* add the EOL char */
- }
- return 0;
- }
-
-
- static int
- domaxping (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- return setshort (&Rspfpingmax, "Max failed pings before deleting adjacency", argc, argv);
- }
-
-
- static int
- dorspfmode (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- if (argc < 2) {
- tputs ("RSPF preferred mode is ");
- if (Rspfownmode == -1)
- tputs ("not set.\n");
- else
- tprintf ("%s.\n", (Rspfownmode & CONNECT_MODE) ? "VC mode" : "Datagram mode");
- return 0;
- }
- switch (*argv[1]) {
- case 'v':
- case 'c':
- case 'V':
- case 'C':
- Rspfownmode = (int) CONNECT_MODE;
- break;
- case 'd':
- case 'D':
- Rspfownmode = (int) DATAGRAM_MODE;
- break;
- case 'n':
- case 'N':
- Rspfownmode = -1;
- break;
- default:
- tputs ("Usage: rspf mode [vc | datagram | none]\n");
- return 1;
- }
- return 0;
- }
-
-
- static int
- dointerface (argc, argv, p)
- int argc;
- char *argv[];
- void *p OPTIONAL;
- {
- struct rspfiface *riface;
- struct iface *iface;
- struct mbuf *bp;
- int h, q;
-
- if (argc < 2) {
- tputs ("Iface Quality Horizon\n");
- for (riface = Rspfifaces; riface != NULLRIFACE; riface = riface->next)
- tprintf ("%-9s%-11d%-11d\n", riface->iface->name, riface->quality,
- riface->horizon);
- return 0;
- }
- if (argc != 4) {
- tputs ("Usage: rspf interface <name> <quality> <horizon>\n");
- return 1;
- }
- if ((iface = if_lookup (argv[1])) == NULLIF) {
- tputs ("No such interface.\n");
- return 1;
- }
- if (iface->broadcast == 0) {
- tprintf ("Broadcast address for interface %s not set\n", argv[1]);
- return 1;
- }
- q = atoi (argv[2]);
- if (q < 1 || q > 127) {
- tputs ("Quality must be between 1 and 127\n");
- return 1;
- }
- h = atoi (argv[3]);
- if (h < 1 || h > 255) {
- tputs ("Horizon must be between 1 and 255\n");
- return 1;
- }
- riface = (struct rspfiface *) callocw (1, sizeof (struct rspfiface));
-
- riface->iface = iface;
- riface->quality = uchar (q);
- riface->horizon = uchar (h);
- riface->next = Rspfifaces;
- if (Rspfifaces == NULLRIFACE) {
- #ifdef AUTOROUTE
- RspfActive = 1; /* Make sure ARP autorouting is off ! - WG7J */
- Ax25_autoroute = 0;
- #endif
- (void) newproc ("RSPF", 2048, rspfmain, 0, NULL, NULL, 0);
- }
- Rspfifaces = riface;
- bp = ambufw (1 + sizeof (int32));
- *bp->data = RSPFE_RRH; /* Send an RRH immediately */
- memcpy (bp->data + 1, &riface, sizeof (riface));
- bp->cnt = bp->size;
- enqueue (&Rspfinq, bp);
- return 0;
- }
-
-
- /* Display accumulated routing updates */
- static int
- doroutes (argc, argv, p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- struct mbuf *bp;
- struct rspfrouter *rr;
-
- if (Rspfifaces == NULLRIFACE) {
- tputs (norspf);
- return 0;
- }
- bp = makeownupdate (INADDR_ANY, 0);
- if (bp == NULLBUF && Rspfrouters == NULLRROUTER) {
- tputs ("No routing information is available.\n");
- return 0;
- }
- if (bp != NULLBUF) {
- tputs (" Local routing update:\n");
- rspfnodedump (NULLFILE, &bp, 0);
- tputc ('\n');
- }
- for (rr = Rspfrouters; rr != NULLRROUTER; rr = rr->next) {
- tprintf (" Time since receipt: %s", tformat (secclock () - rr->time));
- if (rr->subseq != 0)
- tprintf (" Last subseq: %u", uchar (rr->subseq));
- if (rr->sent)
- tputs (" Propagated");
- tputc ('\n');
- if (rr->data != NULLBUF) {
- (void) dup_p (&bp, rr->data, 0, len_p (rr->data));
- rspfnodedump (NULLFILE, &bp, 0);
- tputc ('\n');
- }
- }
- return 0;
- }
-
-
- static int
- dorspfstatus (argc, argv, p)
- int argc OPTIONAL;
- char *argv[] OPTIONAL;
- void *p OPTIONAL;
- {
- struct rspfreasm *re;
- struct rspfadj *adj;
- struct mbuf *bp;
- union rspf rspf;
-
- if (Rspfifaces == NULLRIFACE) {
- tputs (norspf);
- return 0;
- }
- tprintf ("Bad checksum %u Bad version %u Not RSPF interface %u\n",
- Rspf_stat.badcsum, Rspf_stat.badvers, Rspf_stat.norspfiface);
- tprintf ("RRH in %u RRH out %u Update in %u Update out %u\n",
- Rspf_stat.rrhin, Rspf_stat.rrhout, Rspf_stat.updatein,
- Rspf_stat.updateout);
- tprintf ("Non-adjacency update %u Old node report %u Polls sent %u\n",
- Rspf_stat.noadjupdate, Rspf_stat.oldreport, Rspf_stat.outpolls);
- if (Adjs == NULLADJ)
- return 0;
- tputs ("Addr Cost Seq Heard Timer TOS State\n");
- for (adj = Adjs; adj != NULLADJ; adj = adj->next) {
- tprintf ("%-15s %4u %5u %6lu ", inet_ntoa (adj->addr),
- uchar (adj->cost), adj->seq, adj->heard);
- if (run_timer (&adj->timer))
- tprintf ("%5lu/%-5lu",
- read_timer (&adj->timer) / 1000L, dur_timer (&adj->timer) / 1000L);
- else
- tprintf ("%11s", "");
- tprintf (" %3u ", uchar (adj->tos));
- switch (adj->state) {
- case RSPF_TENTATIVE:
- tputs ("Tentative");
- break;
- case RSPF_OK:
- tputs ("OK");
- break;
- case RSPF_SUSPECT:
- tputs ("Suspect");
- break;
- case RSPF_BAD:
- tputs ("Bad");
- break;
- default:
- tputs ("Unknown");
- break;
- }
- tputc ('\n');
- }
- if (run_timer (&Rspfreasmt)) {
- tprintf ("Reassembly timer running: %lu/%lu seconds\n",
- read_timer (&Rspfreasmt) / 1000L, dur_timer (&Rspfreasmt) / 1000L);
- }
- if (Rspfreasmq != NULLRREASM)
- tputs ("Reassembly fragments:\n");
- for (re = Rspfreasmq; re != NULLRREASM; re = re->next) {
- tprintf ("src %s time since last frag %s", inet_ntoa (re->addr),
- tformat ((secclock () - re->time)));
- if (dup_p (&bp, re->data, 0, RSPFPKTLEN) == RSPFPKTLEN &&
- ntohrspf (&rspf, &bp) != -1)
- tprintf (" frag count %u/%u\n", len_q (re->data),
- rspf.pkthdr.fragtot);
- else {
- tputc ('\n');
- free_p (bp);
- continue;
- }
- }
- return 0;
- }
-
- #endif /*RSPF */
-